﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Input;
using Vtron.HipcConfigurationTools.Core;
using Vtron.HipcConfigurationTools.Domain;

namespace Vtron.HipcConfigurationTools
{
    public class EncodedViewModel : INotifyPropertyChanged
    {
        private string versionInfo;
        private string ip;
        private string mask;
        private string gateway;
        private string mac;

        private string resolution;

        //private ICommand searchVersionCommand;
        //private ICommand searchNetConfigCommand;
        private ICommand sumbitNetConfigCommand;
        private ICommand exportLogCommand;
        private ICommand rebootCommand;
        private ICommand searchResolutionCommand;

        public EncodedViewModel()
        {
            //searchVersionCommand = new DelegateCommand<string>(SearchVersion);
            //searchNetConfigCommand = new DelegateCommand<string>(SearchNetConfig);
            sumbitNetConfigCommand = new DelegateCommand<string>(SumbitNetConfig);
            //exportLogCommand = new DelegateCommand<string>(ExportLog);
            rebootCommand = new DelegateCommand<string>(Reboot);
            searchResolutionCommand = new DelegateCommand<string>(SearchResolution);

            Init();
        }

        private void Init()
        {
            SearchVersion(String.Empty);
            SearchNetConfig(String.Empty);
            //SearchResolution(String.Empty);
        }

        public string VersionInfo
        {
            get { return versionInfo; }
            set
            {
                versionInfo = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("VersionInfo"));
                }
            }
        }

        public string Ip
        {
            get { return ip; }
            set
            {
                ip = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Ip"));
                }
            }
        }

        public string Mask
        {
            get { return mask; }
            set
            {
                mask = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Mask"));
                }
            }
        }

        public string Gateway
        {
            get { return gateway; }
            set
            {
                gateway = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Gateway"));
                }
            }
        }

        public string Mac
        {
            get { return mac; }
            set
            {
                mac = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Mac"));
                }
            }
        }

        public string Resolution
        {
            get { return resolution; }
            set
            {
                resolution = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Resolution"));
                }
            }
        }

        //public ICommand SearchVersionCommand { get { return searchVersionCommand; } }
        //public ICommand SearchNetConfigCommand { get { return searchNetConfigCommand; } }
        public ICommand SumbitNetConfigCommand { get { return sumbitNetConfigCommand; } }
        public ICommand ExportLogCommand { get { return exportLogCommand; } }
        public ICommand RebootCommand { get { return rebootCommand; } }
        public ICommand SearchResolutionCommand { get { return searchResolutionCommand; } }

        private void SearchVersion(string obj)
        {
            SocketHandler handler = new SocketHandler();
            T_HIPC_SYS_VERSION_REQ request = new T_HIPC_SYS_VERSION_REQ();
            request.head = new T_HIPC_NET_HEADER() { msgType = 0x8402 };
            T_HIPC_SYS_VERSION_RESP response = handler.Handle<T_HIPC_SYS_VERSION_RESP>(request);

            VersionInfo = String.Format(" 软件：{0}.{1}.{2} \n FPGA：{3}.{4}.{5} \n 硬件：{6} \n PCBA：{7}",
                response.softVersion[2], response.softVersion[1], response.softVersion[0],
                response.fpgaVersion[2], response.fpgaVersion[1], response.fpgaVersion[0],
                response.hardVersion,
                response.pcbaVersion);
        }

        private void SearchNetConfig(string obj)
        {
            SocketHandler handler = new SocketHandler();
            T_HIPC_NET_CONFIG_REQ request = new T_HIPC_NET_CONFIG_REQ();
            request.head = new T_HIPC_NET_HEADER() { msgType = 0x8408 };
            request.netInfo = new T_HIPC_NET_INFO();
            T_HIPC_NET_CONFIG_RESP response = handler.Handle<T_HIPC_NET_CONFIG_RESP>(request);
            Ip = new string((from c in Encoding.ASCII.GetChars(response.netInfo.ipAddress) where !char.IsControl(c) select c).ToArray());
            Mask = new string((from c in Encoding.ASCII.GetChars(response.netInfo.netMask) where !char.IsControl(c) select c).ToArray());
            Gateway = new string((from c in Encoding.ASCII.GetChars(response.netInfo.gatway) where !char.IsControl(c) select c).ToArray());
            Mac = new string((from c in Encoding.ASCII.GetChars(response.netInfo.macAddress) where !char.IsControl(c) select c).ToArray());
        }

        private void SumbitNetConfig(string obj)
        {
            //TODO:
            SocketHandler handler = new SocketHandler();
            T_HIPC_NET_CONFIG_REQ request = new T_HIPC_NET_CONFIG_REQ();
            request.head = new T_HIPC_NET_HEADER() { msgType = 0x840a };
            T_HIPC_NET_INFO netInfo = new T_HIPC_NET_INFO();
            netInfo.gatway = Encoding.Default.GetBytes(gateway);
            netInfo.ipAddress = Encoding.Default.GetBytes(ip);
            netInfo.macAddress = Encoding.Default.GetBytes(mac);
            netInfo.netMask = Encoding.Default.GetBytes(mask);

            T_HIPC_NET_CONFIG_RESP response = handler.Handle<T_HIPC_NET_CONFIG_RESP>(request);
        }

        //private void ExportLog(string obj)
        //{
        //    SocketHandler handler = new SocketHandler();
        //    T_HIPC_SYS_EXPORT_LOG_REQ request = new T_HIPC_SYS_EXPORT_LOG_REQ();
        //    request.head = new T_HIPC_NET_HEADER() { msgType = 0x8546 };

        //    string logStr = String.Empty;
        //    Type responseType = typeof(T_HIPC_SYS_EXPORT_LOG_RESP);
        //    object response;
        //    byte[] Message = Utils.StructToBytes(request);
        //    TcpClient socket = new TcpClient();

        //    IPHostEntry host = Dns.GetHostEntry(ip);
        //    IPAddress[] ipAddress = host.AddressList;
        //    socket.Connect(ipAddress, 5001);
        //    NetworkStream ns = socket.GetStream();

        //    try
        //    {
        //        do
        //        {
        //            ns.Write(Message, 0, Message.Length);
        //            byte[] Recv = new byte[1024];
        //            int NumberOfRecv = 0;
        //            IList<byte> newRecv = new List<byte>();
        //            ns.ReadTimeout = 3000;
        //            do
        //            {
        //                NumberOfRecv = ns.Read(Recv, 0, Recv.Length);
        //                for (int i = 0; i < NumberOfRecv; i++)
        //                {
        //                    newRecv.Add(Recv[i]);
        //                }
        //            }
        //            while (ns.DataAvailable);
        //            byte[] resultRecv = new byte[newRecv.Count];
        //            newRecv.CopyTo(resultRecv, 0);

        //            response = Utils.BytesToStruct(resultRecv, responseType);
        //            if (response == null)
        //            {
        //                break;
        //            }
        //            logStr += Encoding.Default.GetString(((T_HIPC_SYS_EXPORT_LOG_RESP)response).context);

        //        } while (((T_HIPC_SYS_EXPORT_LOG_RESP)response).lastFlag != 1);

        //        socket.Close();
        //        ns.Close();
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //    }

        //    SaveFileDialog dlg = new SaveFileDialog();
        //    dlg.FileName = "Log";
        //    dlg.DefaultExt = ".text";
        //    dlg.Filter = "Text documents (.txt)|*.txt";
        //    Nullable<bool> result = dlg.ShowDialog();
        //    if (result == true)
        //    {
        //        string filename = dlg.FileName;
        //        FileStream fs = new FileStream(filename, FileMode.Create);
        //        StreamWriter sw = new StreamWriter(fs);
        //        sw.Write(logStr);
        //        sw.Close();
        //        fs.Close();
        //    }
        //}

        private void Reboot(string obj)
        {
            SocketHandler handler = new SocketHandler();
            T_HIPC_SYS_REBOOT_REQ request = new T_HIPC_SYS_REBOOT_REQ();
            request.head = new T_HIPC_NET_HEADER() { msgType = 0x8406 };
            T_HIPC_SYS_REBOOT_RESP response = handler.Handle<T_HIPC_SYS_REBOOT_RESP>(request);
        }

        private void SearchResolution(string obj)
        {
            SocketHandler handler = new SocketHandler();
            T_HIPC_VIDEO_RESOLUTION_REQ request = new T_HIPC_VIDEO_RESOLUTION_REQ();
            request.head = new T_HIPC_NET_HEADER() { msgType = 0x8201 };
            T_HIPC_VIDEO_RESOLUTION_RESP response = handler.Handle<T_HIPC_VIDEO_RESOLUTION_RESP>(request);

            //Resolution=Encoding.Default.GetString(response.width
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
